using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System.Net.Http;
using System.Text.Json;

namespace Chat.Backend.Services.Location
{
    /// <summary>
    /// 位置服务 - 处理地理位置相关功能
    /// 转换自Java代码的map模块
    /// </summary>
    public class LocationService : ILocationService
    {
        private readonly ILogger<LocationService> _logger;
        private readonly HttpClient _httpClient;
        private readonly LocationSettings _settings;

        /// <summary>
        /// 构造函数
        /// </summary>
        public LocationService(
            ILogger<LocationService> logger,
            HttpClient httpClient,
            IOptions<LocationSettings> settings)
        {
            _logger = logger;
            _httpClient = httpClient;
            _settings = settings.Value;
        }

        /// <summary>
        /// 获取地址详情
        /// </summary>
        public async Task<LocationDetails> GetLocationDetailsAsync(double latitude, double longitude)
        {
            try
            {
                // 使用Google Maps API获取地址信息
                var url = $"https://maps.googleapis.com/maps/api/geocode/json?latlng={latitude},{longitude}&key={_settings.GoogleMapsApiKey}";
                var response = await _httpClient.GetAsync(url);
                response.EnsureSuccessStatusCode();
                
                var content = await response.Content.ReadAsStringAsync();
                var result = JsonSerializer.Deserialize<GoogleGeocodingResponse>(content);
                
                if (result?.Status != "OK" || result.Results.Count == 0)
                {
                    throw new Exception($"Google Maps API返回错误: {result?.Status}");
                }
                
                // 解析地址信息
                var address = result.Results[0].FormattedAddress;
                var addressComponents = result.Results[0].AddressComponents;
                
                var country = GetAddressComponent(addressComponents, "country");
                var province = GetAddressComponent(addressComponents, "administrative_area_level_1");
                var city = GetAddressComponent(addressComponents, "administrative_area_level_2");
                var district = GetAddressComponent(addressComponents, "administrative_area_level_3");
                var street = GetAddressComponent(addressComponents, "route");
                
                return new LocationDetails
                {
                    Latitude = latitude,
                    Longitude = longitude,
                    Address = address,
                    Country = country,
                    Province = province,
                    City = city,
                    District = district,
                    Street = street
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取地址详情失败: 坐标({latitude},{longitude})");
                throw;
            }
        }

        /// <summary>
        /// 获取附近的用户
        /// </summary>
        public async Task<List<NearbyUser>> GetNearbyUsersAsync(double latitude, double longitude, double radius, int limit = 50)
        {
            try
            {
                // 查询数据库中的用户位置
                // 这里假设使用Redis GEO或者其他数据库的地理位置功能
                
                // 模拟查询结果
                var nearbyUsers = new List<NearbyUser>();
                
                // 在实际应用中，这里应该查询数据库
                
                return nearbyUsers;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取附近用户失败: 坐标({latitude},{longitude})");
                throw;
            }
        }

        /// <summary>
        /// 更新用户位置
        /// </summary>
        public async Task UpdateUserLocationAsync(string userId, double latitude, double longitude)
        {
            try
            {
                // 获取地址详情
                var locationDetails = await GetLocationDetailsAsync(latitude, longitude);
                
                // 创建用户位置对象
                var userLocation = new UserLocation
                {
                    UserId = userId,
                    Latitude = latitude,
                    Longitude = longitude,
                    Address = locationDetails.Address,
                    Country = locationDetails.Country,
                    Province = locationDetails.Province,
                    City = locationDetails.City,
                    District = locationDetails.District,
                    Street = locationDetails.Street,
                    UpdateTime = DateTime.UtcNow
                };
                
                // 保存到数据库
                await SaveUserLocationAsync(userLocation);
                
                _logger.LogInformation($"更新用户位置: 用户 {userId}, 坐标({latitude},{longitude})");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"更新用户位置失败: 用户 {userId}, 坐标({latitude},{longitude})");
                throw;
            }
        }

        /// <summary>
        /// 保存用户位置到数据库
        /// </summary>
        private async Task SaveUserLocationAsync(UserLocation userLocation)
        {
            // 这里应该实现保存用户位置到数据库的逻辑
            // 在实际应用中，可能使用Redis GEO或者其他数据库的地理位置功能
            await Task.CompletedTask;
        }

        /// <summary>
        /// 从地址组件中获取特定类型的组件
        /// </summary>
        private string GetAddressComponent(List<GoogleAddressComponent> components, string type)
        {
            foreach (var component in components)
            {
                if (component.Types.Contains(type))
                {
                    return component.LongName;
                }
            }
            return null;
        }
    }

    /// <summary>
    /// 位置服务接口
    /// </summary>
    public interface ILocationService
    {
        Task<LocationDetails> GetLocationDetailsAsync(double latitude, double longitude);
        Task<List<NearbyUser>> GetNearbyUsersAsync(double latitude, double longitude, double radius, int limit = 50);
        Task UpdateUserLocationAsync(string userId, double latitude, double longitude);
    }
}